package com.example.kcp.utils;

/**
 * byte 工具类
 * @author "陈凯航"
 * @date 2024/10/7
 * @mail "mengxingcn@aliyun.com"
 */
public class BytesUtil {

    /**
     * 两字节对齐
     * @param data
     * @return
     */
    public static byte[] alignTo2(byte[] data) {
        return alignToBytes(data,2);
    }

    /**
     * 四字节对齐
     * @param data
     * @return
     */
    public static byte[] alignTo4(byte[] data) {
        return alignToBytes(data,4);
    }
    /**
     * 八字节对齐
     * @param data
     * @return
     */
    public static byte[] alignTo8(byte[] data) {
        return alignToBytes(data,8);
    }
    /**
     * 十六字节对齐
     * @param data
     * @return
     */
    public static byte[] alignTo16(byte[] data) {
        return alignToBytes(data,16);
    }


    /**
     * 计算给定长度的数值需要填充的字节数，以满足特定的对齐要求
     *
     * @param length 原始长度值
     * @param alignment 对齐要求，即填充后的长度需要是该值的倍数
     * @return 返回需要填充的字节数
     */
    public static int calculatePadding(int length, int alignment) {
        // 计算原始长度对齐要求的余数
        int remainder = length % alignment;
        // 如果余数为0，表示原始长度已经满足对齐要求，不需要填充
        if (remainder == 0) {
            return 0; // 已经对齐
        }
        // 计算并返回需要的填充字节数，使得长度满足对齐要求
        return alignment - remainder; // 需要的填充字节数
    }

    /**
     * 将字节数组数据对齐到指定的对齐方式
     * 对齐操作用于确保数据在内存中的起始地址能够满足特定的对齐要求，
     * 这在处理硬件访问或特定数据结构时可能是必要的
     *
     * @param data 需要对齐的原始字节数组
     * @param alignment 指定的对齐方式，即最终数据的起始地址应该能被该值整除
     * @return 对齐后的字节数组如果输入数据已经满足对齐要求，则直接返回原数据；
     *         否则，返回一个新的字节数组，其中包含原始数据，并通过在末尾添加填充字节达到对齐要求
     */
    public static byte[] alignToBytes(byte[] data, int alignment) {
        // 计算所需的填充字节数，以满足对齐要求
        int padding = calculatePadding(data.length, alignment);
        if (padding == 0) {
            return data; // 已经对齐
        }

        // 创建一个新的字节数组，包含原始数据和填充字节
        byte[] alignedData = new byte[data.length + padding];
        // 将原始数据复制到新的字节数组中
        System.arraycopy(data, 0, alignedData, 0, data.length);
        // 填充剩余的字节
        for (int i = data.length; i < alignedData.length; i++) {
            alignedData[i] = 0; // 填充0
        }

        return alignedData;
    }
    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        return sb.toString().trim();
    }
}
